package com.zrwl.poscloud.xo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zrwl.poscloud.base.entity.Menus;
import com.zrwl.poscloud.base.enums.EStatus;
import com.zrwl.poscloud.base.superI.SuperServiceImpl;
import com.zrwl.poscloud.commons.utils.RedisUtil;
import com.zrwl.poscloud.commons.utils.ResultUtil;
import com.zrwl.poscloud.commons.utils.StringUtils;
import com.zrwl.poscloud.xo.global.MessageConf;
import com.zrwl.poscloud.xo.global.RedisConf;
import com.zrwl.poscloud.xo.global.SQLConf;
import com.zrwl.poscloud.xo.global.SysConf;
import com.zrwl.poscloud.xo.mapper.MenusMapper;
import com.zrwl.poscloud.xo.service.MenusService;
import com.zrwl.poscloud.xo.service.RoleService;
import com.zrwl.poscloud.xo.vo.MenusVO;
import com.zrwl.poscloud.xo.vo.RoleVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 功能菜单 服务实现类
 *
 * @author 刘思童 AutoGenerate
 * @date 2021-04-16
 */
@Service
public class MenusServiceImpl extends SuperServiceImpl<MenusMapper, Menus> implements MenusService {

    @Autowired
    private MenusService menusService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private MenusMapper menusMapper;

    @Override
    public IPage<Menus> getPageList(MenusVO menusVO) {
        QueryWrapper<Menus> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(menusVO.getKeyword()) && !StringUtils.isEmpty(menusVO.getKeyword().trim())) {
            queryWrapper.like("name", menusVO.getKeyword().trim());
        }
        Page<Menus> page = new Page<>();
        page.setCurrent(menusVO.getCurrentPage());
        page.setSize(menusVO.getPageSize());
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        IPage<Menus> pageList = menusService.page(page, queryWrapper);
        List<Menus> list = pageList.getRecords();
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public List<Menus> getAllList(MenusVO menusVO) {
        QueryWrapper<Menus> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByAsc(SQLConf.CREATE_TIME);
        List<Menus> list = menusService.list(queryWrapper);
        return list;
    }

    @Override
    public List<Menus> getRootMenusList() {
        QueryWrapper<Menus> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("super_uid");
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByAsc(SQLConf.CREATE_TIME);
        List<Menus> list = menusService.list(queryWrapper);
        return list;
    }

    @Override
    public Void getChildrenList(MenusVO menusVO) {
        log.debug(menusVO.getName() + "读取子功能");
        List<MenusVO> childrenList = menusMapper.selectChildren(menusVO);
        menusVO.setChildrenList(childrenList);
        for (int i = 0; i < childrenList.size(); i++) {
            getChildrenList(childrenList.get(i));
        }
        return null;
    }

    @Override
    public Void getAllChildrenList(MenusVO menusVO) {
        log.debug(menusVO.getName() + "读取子功能");
        List<MenusVO> childrenList = menusMapper.selectAllChildren(menusVO);
        menusVO.setChildrenList(childrenList);
        for (int i = 0; i < childrenList.size(); i++) {
            childrenList.get(i).setRootUid(menusVO.getRootUid());
            getAllChildrenList(childrenList.get(i));
        }
        return null;
    }

    public Void selectroleMenusList(MenusVO menusVO, List<String> list) {
//        log.debug("功能UID" + list + "      " + "读取子功能");
        List<MenusVO> childrenList = menusMapper.selectroleMenusList(menusVO, list);
        menusVO.setChildrenList(childrenList);
        for (int i = 0; i < childrenList.size(); i++) {
            childrenList.get(i).setRootUid(menusVO.getRootUid());
            selectroleMenusList(childrenList.get(i), list);
        }
        return null;
    }


    @Override
    @Transactional
    public String add(MenusVO menusVO) {
        Menus entity = new Menus();
        BeanUtils.copyProperties(menusVO, entity, SysConf.STATUS);
        entity.insert();
        menusVO.setUid(entity.getUid());
        return ResultUtil.successWithMessage(MessageConf.INSERT_SUCCESS);
    }

    @Override
    @Transactional
    public String edit(MenusVO menusVO) {
        Menus entity = menusService.getById(menusVO.getUid());
        BeanUtils.copyProperties(menusVO, entity);
        //entity.setUpdateTime//已通过填充实现，后续可删除(new Date());
        entity.updateById();
        Set<String> keys = redisUtil.keys(RedisConf.ADMIN_VISIT_MENU + "*");
        redisUtil.delete(keys);
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    @Transactional
    public String delete(MenusVO menusVO) {
        QueryWrapper<Menus> queryWrapper = new QueryWrapper<>();
        queryWrapper.select();
        queryWrapper.eq("super_uid", menusVO.getUid());
        queryWrapper.eq("status", 1);
        List<Menus> list = list(queryWrapper);
        if (list != null && !list.isEmpty()) {
            return ResultUtil.errorWithMessage("不允许删除该功能(请先删除子功能)");
        } else {
            Menus entity = menusService.getById(menusVO.getUid());
            entity.setStatus(EStatus.DISABLED);
            //entity.setUpdateTime//已通过填充实现，后续可删除(new Date());
            entity.updateById();
            Set<String> keys = redisUtil.keys(RedisConf.ADMIN_VISIT_MENU + "*");
            redisUtil.delete(keys);
            return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
        }
    }

    @Override
    public List<Menus> getAllMenuList(MenusVO menusVO) {
        QueryWrapper<Menus> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(menusVO.getKeyword()) && !StringUtils.isEmpty(menusVO.getKeyword().trim())) {
            queryWrapper.like("name", menusVO.getKeyword().trim()).or().like("url", menusVO.getKeyword().trim());
        } else if (StringUtils.isNotEmpty(menusVO.getUid()) && !StringUtils.isEmpty(menusVO.getUid().trim())) {
            queryWrapper.select().eq("super_uid", menusVO.getUid());
        } else {
            queryWrapper.isNull("super_uid");
        }
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByAsc("sort");
        queryWrapper.orderByAsc(SQLConf.CREATE_TIME);
        List<Menus> list = menusService.list(queryWrapper);
        return list;
    }

    @Override
    public List<MenusVO> getMenuTreeList(MenusVO menusVO) {
        List<MenusVO> resultList = new ArrayList<>();
        if (menusVO.getName() != null) {
            Menus menus = menusService.getById(menusVO.getUid());
            BeanUtils.copyProperties(menus, menusVO);
            resultList.add(menusVO);
            menusService.getAllChildrenList(menusVO);
            //以上判断部分留用于条件查找暂时无用
        } else {
            List<Menus> rootList = menusService.getRootMenusList();
            if (!rootList.isEmpty() && rootList != null) {
                for (Menus items : rootList) {
                    MenusVO entity = new MenusVO();
                    BeanUtils.copyProperties(items, entity);
                    //用于前端的树筛选
                    entity.setRootUid(entity.getUid());
                    resultList.add(entity);
                    menusService.getAllChildrenList(entity);
                }
            }
        }
        return resultList;
    }

    @Override
    public List<MenusVO> getOwnMenuTreeList(RoleVO roleVO) {
        String menus = roleService.getById(roleVO.getUid()).getCategoryMenuUids();
        List<MenusVO> menusVOList = JSONObject.parseArray(menus, MenusVO.class);
        return menusVOList;
    }

    @Override
    public List<MenusVO> getNotOwnMenuTreeList(RoleVO roleVO) {
        MenusVO menusVO = new MenusVO();
        List<MenusVO> ownMenusList = menusService.getOwnMenuTreeList(roleVO);
        List<MenusVO> notOwnMenusList = menusService.getMenuTreeList(menusVO);
        for (int i = 0; i < ownMenusList.size(); i++) {
            for (int j = 0; j < notOwnMenusList.size(); j++) {
                if (ownMenusList.get(i).getUid().equals(notOwnMenusList.get(j).getUid())) {
                    MenusVO temp = deleteRepeat(ownMenusList.get(i), notOwnMenusList.get(j));
                    temp.setParentVO(null);
                    break;
                }
            }
        }
        for (int i = 0; i < notOwnMenusList.size(); i++) {
            if (notOwnMenusList.get(i).getChildrenList() == null || notOwnMenusList.get(i).getChildrenList().size() == 0) {
                notOwnMenusList.get(i).setParentVO(null);
                notOwnMenusList.remove(i);
                i--;
            }
        }
        return notOwnMenusList;
    }

    //递归删除重复节点
    public MenusVO deleteRepeat(MenusVO menusVO1, MenusVO menusVO2) {
        List<MenusVO> childrenList1 = menusVO1.getChildrenList();
        List<MenusVO> childrenList2 = menusVO2.getChildrenList();
        for (int i = 0; i < childrenList1.size(); i++) {
            for (int j = 0; j < childrenList2.size(); j++) {
                if (childrenList1.get(i).getUid().equals(childrenList2.get(j).getUid())) {
                    if (childrenList1.get(i).getChildrenList() != null && childrenList1.get(i).getChildrenList().size() != 0
                            && childrenList2.get(j).getChildrenList() != null && childrenList2.get(j).getChildrenList().size() != 0) {
                        childrenList2.get(j).setParentVO(menusVO2);
                        MenusVO temp = deleteRepeat(childrenList1.get(i), childrenList2.get(j));
                        deleteParents(temp);
                        temp.setParentVO(null);
                    } else {
                        if (childrenList2.get(j).getChildrenList() == null || childrenList2.get(j).getChildrenList().size() == 0) {
                            childrenList2.remove(j);
                            if (childrenList2.size() == 0) {
                                menusVO2.setChildrenList(null);
                            }
                        }
                    }
                }
            }
        }
        return menusVO2;
    }

    //递归删除空根节点
    void deleteParents(MenusVO me) {
        if (me.getChildrenList() == null || me.getChildrenList().size() == 0) {
            if (me.getParentVO() != null) {
                me.getParentVO().getChildrenList().remove(me);
                deleteParents(me.getParentVO());
            }
        }
    }

    @Override
    public Map<Integer, List<String>> getLocalOrCloudUrlMode() {
        Map<Integer, List<String>> resultMap = new HashMap<>();
        QueryWrapper<Menus> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        queryWrapper.eq("menu_type", 1);
        List<Menus> menusList = menusService.list(queryWrapper);
        if (menusList != null && menusList.size() > 0) {
            List<String> cloudList = new ArrayList<>();
            List<String> localList = new ArrayList<>();
            resultMap.put(0, cloudList);
            resultMap.put(1, localList);
            for (Menus items : menusList) {
                if (items.getLocalMode() == 0) {
                    cloudList.add(items.getUrl());
                } else {
                    localList.add(items.getUrl());
                }
            }
        }
        return resultMap;
    }

    @Override
    public IPage<Menus> getAPIMenusList(MenusVO menusVO) {
        QueryWrapper<Menus> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(menusVO.getKeyword()) && !StringUtils.isEmpty(menusVO.getKeyword().trim())) {
            queryWrapper.and(wrapper -> wrapper.like("name", menusVO.getKeyword().trim()).or().like("url", menusVO.getKeyword().trim()));
        }
        if (menusVO.getLocalMode() != null) {
            queryWrapper.eq("local_mode", menusVO.getLocalMode());
        }
        if (menusVO.getSuperUid() != null) {
            queryWrapper.eq("super_uid", menusVO.getSuperUid());
        }
        Page<Menus> page = new Page<>();
        page.setCurrent(menusVO.getCurrentPage());
        page.setSize(menusVO.getPageSize());
        queryWrapper.ne(SQLConf.STATUS, EStatus.DISABLED);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.eq("menu_type", 1);
        IPage<Menus> pageList = menusService.page(page, queryWrapper);
        List<Menus> list = pageList.getRecords();
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public String batchMenusModeTrans(List<MenusVO> menusVOList) {
        if (menusVOList.size() <= 0) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        List<String> uidList = new ArrayList<>();
        menusVOList.forEach(item -> uidList.add(item.getUid()));
        Collection<Menus> menusList = menusService.listByIds(uidList);
        menusList.forEach(item -> {
            if (item.getLocalMode() == 0) {
                item.setLocalMode(1);
            } else {
                item.setLocalMode(0);
            }
        });
        Boolean check = menusService.updateBatchById(menusList);
        if (check) {
            return ResultUtil.successWithMessage("转换完成");
        } else {
            return ResultUtil.errorWithMessage("转换失败");
        }
    }

}

